package com.jplus.core.util.verify;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jplus.core.mvc.bean.Result;
import com.jplus.core.util.FormatUtil;
import com.jplus.core.util.JPEL;

public class VerifyUtil {

	private static final Logger logger = LoggerFactory.getLogger(VerifyUtil.class);
	/**
	 * 脚本前缀
	 */
	public static String sePrefix = "js:";

	/**
	 * 执行验证
	 */
	public static Result doVerify(Object pojo) {
		Result res = new Result().OK();
		List<Class<?>> listClazz = getSupClass(pojo.getClass());
		for (Class<?> clazz : listClazz) {
			Field[] fs = clazz.getDeclaredFields();
			for (Field f : fs) {
				f.setAccessible(true);
				Annotation[] as = f.getAnnotations();
				for (Annotation a : as) {
					String cn = a.annotationType().getName();
					if (cn.substring(cn.lastIndexOf(".") + 1).startsWith("V$")) {
						try {
							String val = FormatUtil.toStringTrim(f.get(pojo));
							Method m0 = a.annotationType().getDeclaredMethod("isNull", new Class[] {});
							boolean bon = (boolean) m0.invoke(a, new Object[] {});
							if (bon && FormatUtil.isEmpty(val))
								continue;
							Method m1 = a.annotationType().getDeclaredMethod("regex", new Class[] {});
							String regex = (String) m1.invoke(a, new Object[] {});
							Method m2 = a.annotationType().getDeclaredMethod("retmsg", new Class[] {});
							String retmsg = (String) m2.invoke(a, new Object[] {});
							boolean bo = true;
							if (regex.startsWith("el:")) {
								String js = regex.substring(sePrefix.length()).replaceAll("\\{\\}", val);
								Stack<String> stack = JPEL.createReversePolish(js);
								bo = (boolean) JPEL.calcReversePolish(stack);
							} else if (regex.startsWith("js:")) {
								String js = regex.substring(sePrefix.length()).replaceAll("\\{\\}", val);
								bo = (boolean) JPEL.getSE().eval(js);
							} else {
								bo = Pattern.compile(regex).matcher(val).matches();
							}
							if (!bo)
								return res.FAIL().DATA(retmsg.replaceAll("\\{\\}", f.getName()));
						} catch (Exception e) {
							logger.error("验证发生异常：", e);
						}
					}
				}
			}
		}
		return res;
	}

	private static List<Class<?>> getSupClass(Class<?> clazz) {
		List<Class<?>> list = new ArrayList<Class<?>>();
		list.add(clazz);
		Class<?> temp = clazz.getSuperclass();
		if (!temp.equals(Object.class))
			list.addAll(getSupClass(clazz.getSuperclass()));
		return list;
	}
}
